﻿using System;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

using Crevice2D.Core.Data;
using Crevice2D.Core.Managers;
using Crevice2D.Core.Extension;
using Patyk.Core;

namespace Patyk.Data
{
    public class Player : AnimatedObject
    {
        public Vector2 PrevPosition;

        public bool Active;
        public int Health;
        public float Speed;
        public float RotationSpeed;

        public Color[,] Sprite { get; protected set; }

        public Player() {}

        public void Initialize(Vector2 position, string texture, string animation)
        {
            Origin = new Vector2(11, 50);

            Position = position;
            PrevPosition = position;

            Active = true;
            Health = 100;
            Speed = 4.0f;

            Rotation = MathHelper.ToRadians(90.0f);
            RotationSpeed = MathHelper.ToRadians(0.1f);

            _animationPath = animation;
            _texturePath = texture;
            LoadContent();
        }

        public override bool LoadContent()
        {
            _animation = new Animation();
            var playerTexture = RenderManager.Content.Load<Texture2D>(_animationPath);
            _animation.Initialize(playerTexture, Vector2.Zero, playerTexture.Width, playerTexture.Height, 1, ConstantStrings.AnimationFPS, Color.Blue, 1.0f, true);
            _texture = RenderManager.Content.Load<Texture2D>(_texturePath);
            Sprite = _texture.To2DArray();

            return base.LoadContent();
        }

        public void Update(GameTime gameTime, 
            KeyboardState currentKeyboardState, KeyboardState previousKeyboardState,
            GamePadState currentGamePadState, GamePadState previousGameState,
            MouseState currentMouseState)
        {
            HandleInput(currentKeyboardState, previousKeyboardState, currentGamePadState, previousGameState, currentMouseState);
            UpdatePlayer(gameTime);

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            RenderManager.SpriteBatch.Draw(_texture, Position, null, _animation.Color, Rotation, Origin, _animation.Scale, SpriteEffects.None, 1);
            base.Draw(gameTime);
        }

        private void HandleInput(KeyboardState currentKeyboardState, KeyboardState previousKeyboardState, GamePadState currentGamePadState, GamePadState previousGameState, MouseState currentMouseState)
        {
            HandleKeyboardAndPad(currentKeyboardState, previousKeyboardState, currentGamePadState, previousGameState);

            // TODO: Make sure that the player does not go out of map bounds
            //Position.X = MathHelper.Clamp(Position.X, 0, RenderManager.Viewport.Width - Width/2);
            //Position.Y = MathHelper.Clamp(Position.Y, 0, RenderManager.Viewport.Height - Height/2);
        }


        private void HandleKeyboardAndPad(KeyboardState currentKeyboardState, KeyboardState previousKeyboardState, GamePadState currentGamePadState, GamePadState previousGamePadState)
        {
            PrevPosition = new Vector2(Position.X, Position.Y);

            // Get Thumbstick Controls
            Position.X += currentGamePadState.ThumbSticks.Left.X * Speed;
            Position.Y -= currentGamePadState.ThumbSticks.Left.Y * Speed;

            // Use the Keyboard / Dpad
            if (currentKeyboardState.IsKeyDown(Keys.Left) || currentGamePadState.DPad.Left == ButtonState.Pressed)
            {
                Position.X -= Speed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Right) || currentGamePadState.DPad.Right == ButtonState.Pressed)
            {
                Position.X += Speed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Up) || currentGamePadState.DPad.Up == ButtonState.Pressed)
            {
                Position.Y -= Speed;
            }

            if (currentKeyboardState.IsKeyDown(Keys.Down) || currentGamePadState.DPad.Down == ButtonState.Pressed)
            {
                Position.Y += Speed;
            }
        }

        private void UpdatePlayer(GameTime gameTime)
        {
            var delta = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
            Rotation += delta * RotationSpeed;
            if (Rotation > 2 * Math.PI) Rotation = 0.0f;
        }
    }
}